/*
 * Copyright (C) 2008 Universidade Federal de Campina Grande
 *  
 * This file is part of OurGrid. 
 *
 * OurGrid is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free 
 * Software Foundation, either version 3 of the License, or (at your option) 
 * any later version. 
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details. 
 * 
 * You should have received a copy of the GNU Lesser General Public License 
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package org.ourgrid.discoveryservice;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.ourgrid.common.statistics.beans.ds.DS_PeerStatusChange;
import org.ourgrid.common.statistics.beans.status.PeerStatus;
import org.ourgrid.common.statistics.util.hibernate.HibernateUtil;

/**
 * @author alan
 *
 */
public class PeerStatusChangeUtil {

	/*public static void peerIsUp(DeploymentID peerID) {
		registerPeerStatusChange(peerID, PeerStatus.UP, System.currentTimeMillis());
	}*/
	
	public static void peerIsUp(String peerUserAtServer) {
		registerPeerStatusChange(peerUserAtServer, PeerStatus.UP, System.currentTimeMillis());
	}
	
	/*public static void peerIsDown(DeploymentID peerID) {
		registerPeerStatusChange(peerID, PeerStatus.DOWN, System.currentTimeMillis());
	}*/
	
	public static void peerIsDown(String peerUserAtServer) {
		registerPeerStatusChange(peerUserAtServer, PeerStatus.DOWN, System.currentTimeMillis());
	}
	
	@SuppressWarnings("unchecked")
	public static List<DS_PeerStatusChange> getPeerStatusChangesHistory(long since) {
		
		HibernateUtil.beginTransaction();
		
		List<DS_PeerStatusChange> allPeerStatusChange = null;
		try {
			allPeerStatusChange = new ArrayList<DS_PeerStatusChange>();
			
			Criteria criteria = HibernateUtil.getSession().createCriteria(DS_PeerStatusChange.class)
				.add(Restrictions.ge("timeOfChange", since))
				.addOrder(Order.asc("timeOfChange"));
			
			allPeerStatusChange.addAll(criteria.list());

			HibernateUtil.commitTransaction();
		} catch (HibernateException e) {
			HibernateUtil.rollbackAndCloseSession();
		}
		
		return allPeerStatusChange;
	}
	
	/*public static void registerPeerStatusChange(DeploymentID peerID, 
			PeerStatus status, long timeOfChange) {
		
		Session session = HibernateUtil.getSession();
		HibernateUtil.beginTransaction();
		
		try {
			DS_PeerStatusChange change = new DS_PeerStatusChange();

			change.setCurrentStatus(status);
			change.setLastModified(timeOfChange);
			change.setPeerAddress(peerID.getUserName()+"@"+peerID.getServerName());
			change.setTimeOfChange(timeOfChange);

			session.saveOrUpdate(change);

			HibernateUtil.commitTransaction();
		} catch (HibernateException e) {
			HibernateUtil.rollbackAndCloseSession();
		}
		
	}*/
	
	public static void registerPeerStatusChange(String peerUserAtServer, 
			PeerStatus status, long timeOfChange) {
		
		Session session = HibernateUtil.getSession();
		HibernateUtil.beginTransaction();
		
		try {
			DS_PeerStatusChange change = new DS_PeerStatusChange();

			change.setCurrentStatus(status);
			change.setLastModified(timeOfChange);
			change.setPeerAddress(peerUserAtServer);
			change.setTimeOfChange(timeOfChange);

			session.saveOrUpdate(change);

			HibernateUtil.commitTransaction();
		} catch (HibernateException e) {
			HibernateUtil.rollbackAndCloseSession();
		}
		
	}

	/**
	 * Requirement 502
	 */
	public static void killAllActivePeers(long timeOfChange) {
		Session session = HibernateUtil.getSession();
		HibernateUtil.beginTransaction();
		
		
		try {
			List<DS_PeerStatusChange> changes = session.getNamedQuery("getLastStatusChanges").list();
			
			for (DS_PeerStatusChange peerStatusChange : changes) {
				DS_PeerStatusChange change = new DS_PeerStatusChange();
				change.setCurrentStatus(PeerStatus.DOWN);
				change.setLastModified(timeOfChange);
				change.setPeerAddress(peerStatusChange.getPeerAddress());
				change.setTimeOfChange(timeOfChange);
				
				session.save(change);
			}

			HibernateUtil.commitTransaction();
		} catch (Exception e) {
			HibernateUtil.rollbackAndCloseSession();
		}
	}
	
}
